package spring.boot.admin.service;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import spring.boot.admin.mapper.SysUserMapper;
import spring.boot.admin.model.Pages;
import spring.boot.admin.model.SysUser;


/**
 * 如果整个service都是使用的master数据源，可以放在类上面
 */
@Service
@DS("master")
public class SysUserService extends ServiceImpl<SysUserMapper, SysUser> {

    private static final String DEFAULT_PASS = "123456";

    @Autowired
    private SysUserRoleService sysUserRoleService;

    /**
     * 分页查询用户列表
     * 如果其中一个方法使用了其它数据源，可以单独在方法上面标注
     */
    @DS("two")
    public IPage<SysUser> pageList(Integer page, Integer rows, String realName) {
        if (page == null) {
            page = 1;
        }
        if (rows == null) {
            rows = 10;
        }
        Pages<SysUser> sysRolePage = new Pages<>(page, rows);
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        if (realName != null && realName.trim().length() > 0) {
            wrapper.eq("real_name", realName);
        }
        return page(sysRolePage, wrapper);
    }


    /**
     * 新增用户
     */
    public String insert(String username, Integer age, Integer sex, String realName) {
        SysUser sysUser = new SysUser();
        sysUser.setUsername(username);
        sysUser.setPassword(encodePassword(DEFAULT_PASS));
        sysUser.setAge(age);
        sysUser.setSex(sex);
        sysUser.setRealName(realName);
        sysUser.setCreateTime(String.valueOf(System.currentTimeMillis()));
        sysUser.setEnable(1);
        save(sysUser);
        return "1";
    }


    /**
     * 根据主键删除用户
     */
    public String deleteById(Long id) {
        //根据用户id查询 用户角色 关联关系数量
        int userRoleNum = sysUserRoleService.countByUserId(id);
        if (userRoleNum > 0) {
            return "2";
        } else {
            removeById(id);
            return "1";
        }
    }


    /**
     * 根据主键更新用户信息
     */
    public String updateUserById(Long id, String username, Integer age, Integer sex, String realName) {
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        sysUser.setUsername(username);
        sysUser.setAge(age);
        sysUser.setSex(sex);
        sysUser.setRealName(realName);
        updateById(sysUser);
        return "1";
    }


    /**
     * 根据主键修改用户是否有效字段
     */
    public String updateEnableById(Long id, Integer enable) {
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        sysUser.setEnable(enable);
        updateById(sysUser);
        return "1";
    }


    /**
     * 判断当前用户密码是否正确，是返回false  不正确返回true
     */
    private boolean isNotTrueOldPassword(String oldPassword) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        SysUser sysUser = (SysUser) principal;
        return !new BCryptPasswordEncoder().matches(oldPassword, sysUser.getPassword());
    }


    /**
     * 修改个人登录密码
     */
    public String updatePassword(String oldPassword, String newPassword) {
        if (isNotTrueOldPassword(oldPassword)) {
            return "-2";
        }
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        SysUser sysUser = (SysUser) principal;
        baseMapper.updatePasswordById(sysUser.getId(), encodePassword(newPassword));
        return "1";
    }


    /**
     * 查询用户的信息以及所有的角色和权限
     */
    public SysUser selectByUserName(String username) {
        return baseMapper.selectByUserName(username);
    }


    /**
     * 对用户原始密码进行加密 security
     */
    private String encodePassword(String password) {
        return new BCryptPasswordEncoder().encode(password);
    }


}
